using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Logging;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Authorization;
using Volo.Abp.Domain.Repositories;
using UserManagementService.Users;
using UserManagementService.Permissions;
using UserManagementService.Exceptions;
using UserManagementService.Application.Contracts.Users;
using Volo.Abp.Linq;
using Microsoft.EntityFrameworkCore;

namespace UserManagementService.Users
{
    /// <summary>
    /// 扩展用户应用服务 - 使用自定义User实体
    /// </summary>
    [Authorize(UserManagementPermissions.UserPermissions.Default)]
    public class ExtendedUserAppService : ApplicationService, IExtendedUserAppService
    {
        private readonly IUserRepository _userRepository;
        private readonly IUserPermissionService _userPermissionService;
        private readonly ILogger<ExtendedUserAppService> _logger;
        private readonly IAsyncQueryableExecuter _asyncExecuter;

        public ExtendedUserAppService(
            IUserRepository userRepository,
            IUserPermissionService userPermissionService,
            ILogger<ExtendedUserAppService> logger,
            IAsyncQueryableExecuter asyncExecuter)
        {
            _userRepository = userRepository;
            _userPermissionService = userPermissionService;
            _logger = logger;
            _asyncExecuter = asyncExecuter;
        }

        public virtual async Task<PagedResultDto<UserDto>> GetListAsync(SearchUsersDto input)
        {
            _logger.LogInformation("获取用户列表: Filter={Filter}, Status={Status}, UserType={UserType}, SkipCount={SkipCount}, MaxResultCount={MaxResultCount}",
                input.Filter, input.Status, input.UserType, input.SkipCount, input.MaxResultCount);

            await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Default);

            var queryable = await _userRepository.GetQueryableAsync();

            queryable = queryable
                .WhereIf(!input.Filter.IsNullOrWhiteSpace(),
                    x => x.UserName.Contains(input.Filter) ||
                         x.Email.Contains(input.Filter) ||
                         x.Name!.Contains(input.Filter) ||
                         x.Surname!.Contains(input.Filter) ||
                         x.DisplayName!.Contains(input.Filter))
                .WhereIf(input.Status.HasValue, x => x.Status == input.Status.Value)
                .WhereIf(input.UserType.HasValue, x => x.UserType == input.UserType.Value)
                .WhereIf(input.IsActive.HasValue, x => x.IsActive == input.IsActive.Value)
                .WhereIf(input.StartTime.HasValue, x => x.CreationTime >= input.StartTime.Value)
                .WhereIf(input.EndTime.HasValue, x => x.CreationTime <= input.EndTime.Value);

            var totalCount = await _asyncExecuter.CountAsync(queryable);

            var items = await _asyncExecuter.ToListAsync(
                queryable.OrderBy(x => x.UserName)
                    .PageBy(input.SkipCount, input.MaxResultCount)
            );

            var dtos = ObjectMapper.Map<List<User>, List<UserDto>>(items);

            // 为每个用户获取权限和角色信息
            foreach (var dto in dtos)
            {
                dto.Permissions = await GetUserPermissionsAsync(dto.Id);
                dto.Roles = await GetUserRolesAsync(dto.Id);
            }

            _logger.LogInformation("成功获取用户列表: Count={Count}", dtos.Count);

            return new PagedResultDto<UserDto>(totalCount, dtos);
        }

        public virtual async Task<UserDto> GetAsync(Guid id)
        {
            _logger.LogInformation("获取用户详情: Id={Id}", id);

            await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Default);

            var user = await _userRepository.GetAsync(id);

            var userDto = ObjectMapper.Map<User, UserDto>(user);
            userDto.Permissions = await GetUserPermissionsAsync(id);
            userDto.Roles = await GetUserRolesAsync(id);

            _logger.LogInformation("成功获取用户详情: Id={Id}, UserName={UserName}", id, userDto.UserName);

            return userDto;
        }

        [Authorize(UserManagementPermissions.UserPermissions.Create)]
        public virtual async Task<UserDto> CreateAsync(CreateUserDto input)
        {
            _logger.LogInformation("创建用户: UserName={UserName}, Email={Email}, Name={Name}, Surname={Surname}",
                input.UserName, input.Email, input.Name, input.Surname);

            await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Create);

            // 检查用户名是否已存在
            if (await _userRepository.IsUserNameExistAsync(input.UserName, CurrentTenant.Id))
            {
                throw new UserNameAlreadyExistsException(input.UserName);
            }

            // 检查邮箱是否已存在
            if (!input.Email.IsNullOrWhiteSpace() &&
                await _userRepository.IsEmailExistAsync(input.Email, CurrentTenant.Id))
            {
                throw new UserEmailAlreadyExistsException(input.Email);
            }

            // 检查手机号是否已存在
            if (!input.PhoneNumber.IsNullOrWhiteSpace() &&
                await _userRepository.IsPhoneNumberExistAsync(input.PhoneNumber, CurrentTenant.Id))
            {
                throw new UserPhoneNumberAlreadyExistsException(input.PhoneNumber);
            }

            var user = new User(
                GuidGenerator.Create(),
                input.UserName,
                input.Email,
                input.Name,
                input.Surname,
                CurrentTenant.Id
            );

            // 设置手机号
            if (!input.PhoneNumber.IsNullOrWhiteSpace())
            {
                user.SetPhoneNumber(input.PhoneNumber);
            }

            // 设置密码
            if (!input.Password.IsNullOrWhiteSpace())
            {
                // TODO: 使用密码哈希服务
                var passwordHash = HashPassword(input.Password);
                user.SetPassword(passwordHash);
            }

            // 设置用户类型和状态
            if (input.UserType.HasValue)
            {
                // 通过反射设置私有属性UserType
                var userTypeProperty = user.GetType().GetProperty("UserType");
                userTypeProperty?.SetValue(user, input.UserType.Value);
            }

            // 设置头像URL
            if (!input.AvatarUrl.IsNullOrWhiteSpace())
            {
                user.SetAvatarUrl(input.AvatarUrl);
            }

            // 设置个人简介
            if (!input.Bio.IsNullOrWhiteSpace())
            {
                user.SetBio(input.Bio);
            }

            // 分配角色
            if (input.RoleIds?.Any() == true)
            {
                foreach (var roleId in input.RoleIds)
                {
                    user.AddRole(roleId);
                }
            }

            await _userRepository.InsertAsync(user, autoSave: true);

            var userDto = ObjectMapper.Map<User, UserDto>(user);
            userDto.Permissions = await GetUserPermissionsAsync(user.Id);
            userDto.Roles = await GetUserRolesAsync(user.Id);

            _logger.LogInformation("成功创建用户: Id={Id}, UserName={UserName}",
                user.Id, user.UserName);

            return userDto;
        }

        [Authorize(UserManagementPermissions.UserPermissions.Edit)]
        public virtual async Task<UserDto> UpdateAsync(Guid id, UpdateUserDto input)
        {
            _logger.LogInformation("更新用户: Id={Id}, UserName={UserName}, Email={Email}",
                id, input.UserName, input.Email);

            await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Edit);

            var user = await _userRepository.GetAsync(id);

            // 检查用户名是否与其他用户冲突
            if (input.UserName != user.UserName &&
                await _userRepository.IsUserNameExistAsync(input.UserName, CurrentTenant.Id, id))
            {
                throw new UserNameAlreadyExistsException(input.UserName);
            }

            // 检查邮箱是否与其他用户冲突
            if (!input.Email.IsNullOrWhiteSpace() &&
                input.Email != user.Email &&
                await _userRepository.IsEmailExistAsync(input.Email, CurrentTenant.Id, id))
            {
                throw new UserEmailAlreadyExistsException(input.Email);
            }

            // 检查手机号是否与其他用户冲突
            if (!input.PhoneNumber.IsNullOrWhiteSpace() &&
                input.PhoneNumber != user.PhoneNumber &&
                await _userRepository.IsPhoneNumberExistAsync(input.PhoneNumber, CurrentTenant.Id, id))
            {
                throw new UserPhoneNumberAlreadyExistsException(input.PhoneNumber);
            }

            // 更新基本信息
            user.SetUserName(input.UserName);
            user.SetEmail(input.Email);
            user.SetName(input.Name);
            user.SetSurname(input.Surname);

            // 更新手机号
            if (!input.PhoneNumber.IsNullOrWhiteSpace())
            {
                user.SetPhoneNumber(input.PhoneNumber);
            }

            // 更新头像URL
            if (!input.AvatarUrl.IsNullOrWhiteSpace())
            {
                user.SetAvatarUrl(input.AvatarUrl);
            }

            // 更新个人简介
            if (!input.Bio.IsNullOrWhiteSpace())
            {
                user.SetBio(input.Bio);
            }

            await _userRepository.UpdateAsync(user, autoSave: true);

            var userDto = ObjectMapper.Map<User, UserDto>(user);
            userDto.Permissions = await GetUserPermissionsAsync(id);
            userDto.Roles = await GetUserRolesAsync(id);

            _logger.LogInformation("成功更新用户: Id={Id}, UserName={UserName}",
                id, user.UserName);

            return userDto;
        }

        [Authorize(UserManagementPermissions.UserPermissions.Delete)]
        public virtual async Task DeleteAsync(Guid id)
        {
            _logger.LogInformation("删除用户: Id={Id}", id);

            await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Delete);

            var user = await _userRepository.GetAsync(id);

            await _userRepository.DeleteAsync(user, autoSave: true);

            // 清除用户权限缓存
            await _userPermissionService.RefreshUserPermissionCacheAsync(id);

            _logger.LogInformation("成功删除用户: Id={Id}, UserName={UserName}",
                id, user.UserName);
        }

        [Authorize(UserManagementPermissions.UserPermissions.Edit)]
        public virtual async Task<UserDto> ActivateAsync(Guid id)
        {
            _logger.LogInformation("激活用户: Id={Id}", id);

            await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Edit);

            var user = await _userRepository.GetAsync(id);

            if (user.Status == UserStatus.Active)
            {
                throw new UserAlreadyActiveException(user.Id, user.UserName);
            }

            user.Activate();
            await _userRepository.UpdateAsync(user, autoSave: true);

            var userDto = ObjectMapper.Map<User, UserDto>(user);

            _logger.LogInformation("成功激活用户: Id={Id}, UserName={UserName}",
                id, user.UserName);

            return userDto;
        }

        [Authorize(UserManagementPermissions.UserPermissions.Edit)]
        public virtual async Task<UserDto> DeactivateAsync(Guid id)
        {
            _logger.LogInformation("停用用户: Id={Id}", id);

            await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Edit);

            var user = await _userRepository.GetAsync(id);

            if (user.Status == UserStatus.Disabled)
            {
                throw new UserAlreadyInactiveException(user.Id, user.UserName);
            }

            user.Deactivate();
            await _userRepository.UpdateAsync(user, autoSave: true);

            var userDto = ObjectMapper.Map<User, UserDto>(user);

            _logger.LogInformation("成功停用用户: Id={Id}, UserName={UserName}",
                id, user.UserName);

            return userDto;
        }

        [Authorize(UserManagementPermissions.UserPermissions.Edit)]
        public virtual async Task<UserDto> ResetPasswordAsync(Guid id, ResetPasswordDto input)
        {
            _logger.LogInformation("重置用户密码: Id={Id}", id);

            await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Edit);

            var user = await _userRepository.GetAsync(id);

            if (!input.NewPassword.IsNullOrWhiteSpace())
            {
                var passwordHash = HashPassword(input.NewPassword);
                user.SetPassword(passwordHash);
            }

            await _userRepository.UpdateAsync(user, autoSave: true);

            var userDto = ObjectMapper.Map<User, UserDto>(user);

            _logger.LogInformation("成功重置用户密码: Id={Id}", id);

            return userDto;
        }

        public virtual async Task<List<string>> GetPermissionsAsync(Guid id)
        {
            _logger.LogInformation("获取用户权限: Id={Id}", id);

            await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Default);

            var permissions = await _userPermissionService.GetUserPermissionsAsync(id);

            _logger.LogInformation("成功获取用户权限: Id={Id}, PermissionCount={Count}",
                id, permissions.Count);

            return permissions;
        }

        [Authorize(UserManagementPermissions.UserPermissions.Edit)]
        public virtual async Task AssignRolesAsync(Guid id, AssignRolesDto input)
        {
            _logger.LogInformation("为用户分配角色: Id={Id}, RoleIds={RoleIds}",
                id, string.Join(",", input.RoleIds));

            await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Edit);

            var user = await _userRepository.GetAsync(id);

            // 先移除所有现有角色
            // TODO: 实现清除所有角色的逻辑

            // 分配新角色
            foreach (var roleId in input.RoleIds)
            {
                user.AddRole(roleId);
            }

            await _userRepository.UpdateAsync(user, autoSave: true);

            _logger.LogInformation("成功为用户分配角色: Id={Id}, RoleCount={Count}",
                id, input.RoleIds.Count);
        }

        [Authorize(UserManagementPermissions.UserPermissions.Edit)]
        public virtual async Task RemoveRolesAsync(Guid id, RemoveRolesDto input)
        {
            _logger.LogInformation("移除用户角色: Id={Id}, RoleIds={RoleIds}",
                id, string.Join(",", input.RoleIds));

            await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Edit);

            var user = await _userRepository.GetAsync(id);

            // 移除指定角色
            foreach (var roleId in input.RoleIds)
            {
                user.RemoveRole(roleId);
            }

            await _userRepository.UpdateAsync(user, autoSave: true);

            _logger.LogInformation("成功移除用户角色: Id={Id}, RoleCount={Count}",
                id, input.RoleIds.Count);
        }

        [Authorize(UserManagementPermissions.UserPermissions.Edit)]
        public virtual async Task<UserDto> BatchUpdateStatusAsync(BatchUpdateUserStatusDto input)
        {
            _logger.LogInformation("批量更新用户状态: UserIds={UserIds}, Status={Status}",
                string.Join(",", input.UserIds), input.Status);

            await CheckPolicyAsync(UserManagementPermissions.UserPermissions.Edit);

            var affectedCount = await _userRepository.BatchUpdateStatusAsync(input.UserIds, input.Status, CurrentTenant.Id);

            _logger.LogInformation("成功批量更新用户状态: AffectedCount={AffectedCount}", affectedCount);

            return new UserDto
            {
                Id = Guid.Empty, // 这是一个批量操作的结果，不需要具体的用户ID
                UserName = $"批量操作: {affectedCount} 个用户",
                Email = "batch@operation.com"
            };
        }

        private async Task<List<string>> GetUserPermissionsAsync(Guid userId)
        {
            try
            {
                return await _userPermissionService.GetUserPermissionsAsync(userId);
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "获取用户权限失败: UserId={UserId}, Error={Error}",
                    userId, ex.Message);
                return new List<string>();
            }
        }

        private async Task<List<string>> GetUserRolesAsync(Guid userId)
        {
            try
            {
                // TODO: 实现获取用户角色的逻辑
                return new List<string>();
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "获取用户角色失败: UserId={UserId}, Error={Error}",
                    userId, ex.Message);
                return new List<string>();
            }
        }

        private string HashPassword(string password)
        {
            // TODO: 使用ABP的密码哈希服务
            // 暂时返回简单的哈希
            return BCrypt.Net.BCrypt.HashPassword(password);
        }

        protected override async Task CheckPolicyAsync(string? policyName)
        {
            if (!await AuthorizationService.IsGrantedAsync(policyName))
            {
                throw new AbpAuthorizationException($"未授权访问: {policyName}");
            }
        }
    }

    /// <summary>
    /// 用户手机号已存在异常
    /// </summary>
    public class UserPhoneNumberAlreadyExistsException : BusinessException
    {
        public UserPhoneNumberAlreadyExistsException(string phoneNumber) : base(UserManagementServiceErrorCodes.UserPhoneNumberAlreadyExists)
        {
            WithData("phoneNumber", phoneNumber);
        }
    }
}